#-*- coding: utf-8 -*-
from django.http import HttpResponse, HttpRequest, HttpResponseForbidden

import urllib2
import math
import operator
import collections
import re
import traceback

from util import generic_converter

def hello(request):
	html = "ciao mondo"
	return HttpResponse(html)


def trovapernome(request, aggregatori, nome):
		# mi splitto in una lista gli aggregatori (da 1 a N)
		nome = nome.replace(' ','%20')
		list_aggr = aggregatori.split('/')	
		locations = {}
		accept = request.META['CONTENT_TYPE']
		metodo = request.META['REQUEST_METHOD']
		if metodo == 'POST':
			return  HttpResponseForbidden
		for aggr in list_aggr:
			try:
				# per ogni aggregatore nella lista effettuo la richiesta con il realtivo header
				request = urllib2.Request("http://127.0.0.1:8000/%s/name/contains/%s/" % (aggr, nome))
				request.add_header('Accept' , 'text/turtle,text/csv,application/json,application/xml')
				send_request = urllib2.urlopen(request)
				# mi ricavo il content-type dalla risposta dell'aggregatore e i dati che mi fornisce
				mime_type = send_request.info().getheader('Content-Type')
				data_raw = send_request.read()
				# controllo se il nome non e' stato trovato, nel caso mi restituisce i dati xml,json,csv vuoti che pesano 23,64 o 792
				# se non sono vuoti converto i dati in locations inserendoli nel dizionario locations
				locations.update(generic_converter.convert2locations(data_raw, mime_type))
				# faccio quello che voglio con i dati, controllo l'accept dela richista del narratore e fornisco il data_raw con il formato desiderato
			except Exception as ex:
				print ex
	
		response = generic_converter.convert2rawdata(locations, 'application/xml')
		return HttpResponse(response)


# calcolo della distanza fra due punti sul globo
def distance_on_unit_sphere(lat1, long1, lat2, long2):
	# spherical coordinates in radians.
	degrees_to_radians = math.pi / 180.0
	phi1 = (90.0 - lat1) * degrees_to_radians
	phi2 = (90.0 - lat2) * degrees_to_radians
	# theta = longitude
	theta1 = long1 * degrees_to_radians
	theta2 = long2 * degrees_to_radians
	cos = (math.sin(phi1) * math.sin(phi2) * math.cos(theta1 - theta2) + 
	math.cos(phi1) * math.cos(phi2))
	arc = math.acos(cos)
	distanza = arc * 6372.795
	return distanza

def distanza(request, lat1, long1, lat2, long2):
	try:
		lat1 = (float(lat1))
		long1 = (float(long1))
		lat2 = (float(lat2))
		long2 = (float(long2))
		# moltiplico la distanza sferica per il raggio della terra
		dist = distance_on_unit_sphere(lat1, long1, lat2, long2)
		if dist < 1:
			return HttpResponse("%.0f m" % (dist * 1000))
		else:
			return HttpResponse("%.2f Km" % (dist))
	except Exception, ex:
		#c'è stato un qualche errore nell'elaborazione della richiesta
		traceback.print_exc()
		response = HttpResponse(str(ex), 'text/plain', 406)
		return response
	
def descrizione(request, aggr, id):
	try:
		locations = {}
		request = urllib2.Request("http://127.0.0.1:8000/%s/id/contains/%s/" % (aggr, id))
		request.add_header('Accept' , 'text/turtle,text/csv,application/json,application/xml')
		send_request = urllib2.urlopen(request)
		mime_type = send_request.info().getheader('Content-Type')
		data_raw = send_request.read()
		locations.update(generic_converter.convert2locations(data_raw, mime_type))
		descr = "<b>%s </b><b>%s</b></br> Indirizzo: <b>%s</b></br> Numero: <b>%s</b></br> Orari Apertura: <b>%s</b></br> Date Chiusura: <b>%s</b>" % (locations[id].category.upper(), locations[id].name.upper(), locations[id].address, locations[id].tel, locations[id].opening_settimanale, locations[id].closing)
		response = HttpResponse(descr)
	except Exception, ex:
		#c'è stato un qualche errore nell'elaborazione della richiesta
		traceback.print_exc()
		response = HttpResponse(str(ex), 'text/plain', 406)
	return response

def vicino_a(request, aggregatori, lat1, long1, massimo):
	massimo = (int(massimo))
	lat1 = (float(lat1))
	long1 = (float(long1))
	list_aggr = aggregatori.split('/')	
	locations = {}
	locations_vicine = {}
	distanze = {}
	# stessa cosa di trovapernome
	for aggr in list_aggr:
		request = urllib2.Request("http://127.0.0.1:8000/%s" % (aggr))
		request.add_header('Accept' , 'text/turtle,text/csv,application/json,application/xml')
		send_request = urllib2.urlopen(request)
		mime_type = send_request.info().getheader('Content-Type')
		data_raw = send_request.read()
		locations.update(generic_converter.convert2locations(data_raw, mime_type))
	# prendo l'indice (id) delle location
	for l in locations:
		# popolo un nuovo dizionario con indice l'id e come elemento associato la distanza dal punto
		distanze.update({l: distance_on_unit_sphere(lat1, long1, locations[l].lat, locations[l].long)})
		# questa funzione prende il dizionario di sopra, lo ordina in base all'elemento (1) e mi restituisce una lista, degli id, dei primi (massimo) risultati 
	sorted_dist = collections.OrderedDict(sorted(distanze.iteritems(), key=operator.itemgetter(1))[:massimo])
	# nei cicli confronto l'indice con quello del dizionario di tutte le locations, quando trovo quello uguale lo metto in un nuovo dizionario
	for p in sorted_dist:
		for l in locations:
			if p == l:
				locations_vicine.update({p: locations[l]})
	raw_data = generic_converter.convert2rawdata(locations_vicine, 'application/xml')
	return HttpResponse(raw_data)

def entro_raggio(request, aggregatori, lat1, long1, raggio):
	raggio = (int(raggio))
	lat1 = (float(lat1))
	long1 = (float(long1))
	list_aggr = aggregatori.split('/')	
	locations = {}
	locations_raggio = {}
	for aggr in list_aggr:
		request = urllib2.Request("http://127.0.0.1:8000/%s" % (aggr))
		request.add_header('Accept' , 'text/turtle,text/csv,application/json,application/xml')
		send_request = urllib2.urlopen(request)
		mime_type = send_request.info().getheader('Content-Type')
		data_raw = send_request.read()
		locations.update(generic_converter.convert2locations(data_raw, mime_type))
	for l in locations:
		if distance_on_unit_sphere(lat1, long1, locations[l].lat, locations[l].long) * 1000 < raggio:
			locations_raggio.update({l: locations[l]})
	raw_data = generic_converter.convert2rawdata(locations_raggio, 'application/xml')
	return HttpResponse(raw_data)
def trova_giorno(giorno):
	giorno = re.findall('[a-z]{3}', giorno)
	return giorno[0]
def trova_ora(ora):
	ora = re.findall('[\d]{4}', ora)
	return ora
def compreso(orario,ora1,ora2):
	if ',' in orario:
		orario.split(',')
		coppie_orari = orario.split(',')
		orari1 = coppie_orari[0].split('-')
		orari2 = coppie_orari[1].split('-')
		if ora1 >= orari1[0] and ora2 <= orari1[1] or ora1 >= orari2[0] and ora2 <= orari2[1]:
			return 'aperto'
		else:
			return 'chiuso'
	else :
		orario = orario.split('-')
		if ora1 >= orario[0]  and ora2 <= orario[1]:
			return 'aperto'
		else:
			return 'chiuso'
	
def aperto(request, lista, ora):
	try:
		giorno_orario = trova_giorno(ora)
		orario = trova_ora(ora)
		provo = re.findall('([a-z]*,?[a-z]*,?[a-z]*,?[a-z]*,?[a-z]*,?[a-z]*,?[a-z]{3}:[\d]{4}-[\d]{4},?[\d]*-?[\d]*)', lista)
		list = {}
		for p in provo:
			prov = p.split(':')
			list.update({prov[0] : prov[1]})
		for p in list:
			if giorno_orario in p:
				response = HttpResponse(compreso(list[p],orario[0],orario[1]))
			else:
				response = HttpResponse('chiuso', 'text/plain')
	except Exception, ex:
		#c'è stato un qualche errore nell'elaborazione della richiesta
		traceback.print_exc()
		response = HttpResponse(str(ex), 'text/plain', 406)
	return response